package org.example;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.io.*;
import java.net.Socket;
import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;


class communication implements Serializable{
    int flag;
    String user;
    String message;

    communication(int i1, String s2,String s3){
        this.flag=i1;
        this.user=s2;
        this.message=s3;
    }

    @Override
    public String toString(){
        return "[flag]:"+flag+"   [user]:"+user+"    [message]:"+message;
    }
}

class RButton extends JButton {
    public RButton(String label) {
        super(label);
        // 这些声明把按钮扩展为一个圆而不是一个椭圆。
        Dimension size = getPreferredSize();
        size.width = size.height = Math.max(size.width,
                size.height);
        setPreferredSize(size);
        //这个调用使JButton不画背景，而允许我们画一个圆的背景。
        setContentAreaFilled(false);
        this.setBackground(Color.PINK);
    }

    // 画圆的背景和标签
    protected void paintComponent(Graphics g) {
        if (getModel().isArmed()) {
            // 你可以选一个高亮的颜色作为圆形按钮类的属性
            g.setColor(Color.orange);
        } else {
            g.setColor(getBackground());
        }
        g.fillOval(0, 0, getSize().width - 1,
                getSize().height - 1);
        //这个调用会画一个标签和焦点矩形。
        super.paintComponent(g);
    }

    // 用简单的弧画按钮的边界。
    protected void paintBorder(Graphics g) {
        g.setColor(getForeground());
        g.drawOval(0, 0, getSize().width - 1,
                getSize().height - 1);
    }

    // 侦测点击事件
    Shape shape;

    public boolean contains(int x, int y) {
        // 如果按钮改变大小，产生一个新的形状对象。
        if (shape == null ||
                !shape.getBounds().equals(getBounds())) {
            shape = new Ellipse2D.Float(0, 0,
                    getWidth(), getHeight());
        }
        return shape.contains(x, y);
    }
}

public class GUI{
    Connection connection;
    ObjectInputStream is;
    ObjectOutputStream os;
    JFrame f;
    JPanel hallPanel;
    JPanel homePanel;
    int width=1500;
    int height=1000;
    String nowUsername=null;
    String otherUser;
    private int sec;
    private int min;
    private int hour;
    private Socket socket;
    //对话框
    JTextArea recordTalk;
    int state;
    int chessColor;//1代表黑棋，2代表白棋
    //计时器
    JLabel time;//计时器
    int allNum;
    int victory;
    int flushTime;
    java.util.List<JLabel> blackChess=new ArrayList<>();//黑棋在棋盘上绘制的图形
    java.util.List<JLabel> whiteChess=new ArrayList<>();//白棋在棋盘上绘制的图形
    int[][] boardRecord=new int[19][19];//棋盘落子情况记录


    private void listener(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                    while(true){
                        try {
                            if(socket.isClosed()) return;
                            communication content=(communication) is.readObject();
                            if(content.flag==Const.regret){
                                int temp=Integer.parseInt(content.message);
                                if(temp==0){
                                    int n = JOptionPane.showConfirmDialog(null, "对方正在请求悔棋，是否同意？", "标题",JOptionPane.YES_NO_OPTION)+1;
                                    if(n==1){
                                        removeLastChess();
                                    }
                                    sendMessage(Const.regret, content.user, ""+n);
                                }else if(temp==1){
                                    removeLastChess();
                                }else{
                                    JOptionPane.showMessageDialog(null, "对方拒绝了您的申请");
                                }
                            }
                            if(content.flag==Const.end){
                                if(content.message.equals("exit")){
                                    int n = JOptionPane.showConfirmDialog(null, "对方退出了房间。点击《是》将为您创建新房间，点击《否》需要您手动退出房间", "标题",JOptionPane.YES_NO_OPTION);
                                    if(n==0) {
                                        sendMessage(Const.end,nowUsername,"create");
                                        cleanBoard();
                                        state=Const.searching;
                                    }else state=Const.end;
                                }else{
                                    int win=Integer.parseInt(content.message);
                                    if(win==1){
                                        recordTalk.append("【系统】恭喜您赢了！\n");
                                        JOptionPane.showMessageDialog(null, "恭喜您赢了！");
                                    }else{
                                        recordTalk.append("【系统】游戏结束！很遗憾您输了\n");
                                        JOptionPane.showMessageDialog(null, "游戏结束！很遗憾您输了");
                                    }
                                    f.repaint();
                                    state=Const.end;
                                }
                            }
                            if(content.flag==Const.restart){
                                int restart_message=Integer.parseInt(content.message);
                                if(restart_message==0){
                                    int n = JOptionPane.showConfirmDialog(null, "对方正在请求重新开始，是否同意？", "标题",JOptionPane.YES_NO_OPTION)+1;
                                    sendMessage(Const.restart,null,""+n);
                                    if(n==1){
                                        doRestart();
                                    }
                                }
                                else if(restart_message==1){
                                    doRestart();
                                }
                                else JOptionPane.showMessageDialog(null, "对方拒绝了您的请求");
                            }
                            if(content.flag==Const.play){
                                int x=Integer.parseInt(content.message.substring(0,content.message.indexOf(" ")));
                                int y=Integer.parseInt(content.message.substring(content.message.indexOf(" ")+1));
                                int i=(x-25)/43;
                                int j=(y-85)/43;
                                if(chessColor==1){
                                    boardRecord[i][j]=2;
                                    drawChess(x,y,2);
                                }else{
                                    boardRecord[i][j]=1;
                                    drawChess(x,y,1);
                                }
                                state=Const.play;
                            }
                            if(content.flag==Const.ask){
                                if(state==Const.searching){
                                    int n = JOptionPane.showConfirmDialog(null, content.user+" 正在请求加入您的房间，是否同意？", "标题",JOptionPane.YES_NO_OPTION);
                                    if(n==0){
                                        state=Const.response;
                                        otherUser=content.user;
                                        sendMessage(Const.response,otherUser,"ok");
                                    }
                                }else{
                                    sendMessage(Const.response,null,"no");
                                }
                            }
                            if(content.flag==Const.response){
                                if(content.message!=null&&content.message.equals("ok")) sendMessage(Const.matched,nowUsername,null);
                                else {
                                    JOptionPane.showMessageDialog(null, "房主拒绝您的加入");
                                    state=Const.login;
                                }
                            }
                            if(content.flag==Const.send){
                                String source="【"+otherUser+"】 ";
                                source = getStringTime(source);
                                source+='\n';
                                recordTalk.append(source);
                                recordTalk.append(content.message+"\n");
                            }
                            if(content.flag==Const.matched){
                                if(state==Const.ask){
                                    f.remove(hallPanel);
                                    initRoom();
                                    f.repaint();
                                }
                                recordTalk.append("匹配对手成功！对手为:"+otherUser+"\n");

                                String message="匹配对手成功！";
                                if(content.message.equals("black")){
                                    chessColor=1;
                                    state=Const.play;
                                    message+="您执黑棋，请您先下\n";
                                }
                                else{
                                    chessColor=2;
                                    state=Const.wait;
                                    message+="您执白棋，请您后下\n";
                                }
                                recordTalk.append(message);

                                int delay = 1000;    //时间间隔，单位为毫秒
                                ActionListener timer = new ActionListener() {
                                    @Override
                                    public void actionPerformed(ActionEvent e) {
                                        if(state==Const.play||state==Const.wait){
                                            sec += 1;
                                            if (sec == 60) {
                                                min += 1;
                                                sec = 0;
                                            }
                                            if (min == 60) {
                                                min = 0;
                                                hour += 1;
                                            }
                                            String txt = "对局进行时长  ";
                                            txt = getStringTime(txt);
                                            time.setText(txt);
                                        }
                                    }
                                };
                                new Timer(delay,timer).start();
                            }
                        } catch (Exception e) {
                        }

                    }
                }
        }).start();
    }

    private void doRestart() {
        cleanBoard();
        JOptionPane.showMessageDialog(null, "对方同意，即将重新开始...");
        String message;
        sec=0;
        min=0;
        hour=0;
        if(chessColor==1) {
            state= Const.play;
            message="您执黑棋，请您先下\n";
        }
        else {
            state=Const.wait;
            message="您执白棋，请您后下\n";
        }
        recordTalk.append(message);
    }

    private void removeLastChess() {
        if(!blackChess.isEmpty()){
            JLabel tempBlack=blackChess.get(blackChess.size()-1);
            int x=tempBlack.getX();
            int y=tempBlack.getY();
            int i=(x-25)/43;
            int j=(y-85)/43;
            boardRecord[i][j]=0;
            f.remove(tempBlack);
            f.repaint();
            blackChess.remove(blackChess.size()-1);
        }
        if(!whiteChess.isEmpty()){
            JLabel tempWhite=whiteChess.get(whiteChess.size()-1);
            int x=tempWhite.getX();
            int y=tempWhite.getY();
            int i=(x-25)/43;
            int j=(y-85)/43;
            boardRecord[i][j]=0;
            f.remove(tempWhite);
            f.repaint();
            whiteChess.remove(whiteChess.size()-1);
        }
    }

    private void cleanBoard() {
        for(int i=0;i<blackChess.size();i++){
            JLabel temp=blackChess.get(i);
            f.remove(temp);
        }
        for(int i=0;i<whiteChess.size();i++){
            JLabel temp=whiteChess.get(i);
            f.remove(temp);
        }
        for(int i=0;i<19;i++){
            for(int j=0;j<19;j++){
                boardRecord[i][j]=0;
            }
        }
        f.repaint();
        blackChess.clear();
        whiteChess.clear();
    }

    public GUI(Connection connection, ObjectOutputStream os, ObjectInputStream is, Socket socket) throws Exception {
        try{
            this.connection = connection;
            this.is = is;
            this.os = os;
            this.socket=socket;
            initFrame();
        }catch (Exception e){
            System.out.println(Arrays.toString(e.getStackTrace()));
        }finally {
            sendMessage(Const.logout,nowUsername,null);
        }
    }

    private void initHome(){
        homePanel=new JPanel();
        homePanel.setVisible(true);
        homePanel.setBounds(0,0,width,height);


        //创建登录界面背景图片
        ImageIcon image = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\background.jpg");
        //图片自适应窗口尺寸
        image.setImage(image.getImage().getScaledInstance(1500,1000,Image.SCALE_DEFAULT ));
        JLabel background=new JLabel();
        background.setIcon(image);
        background.setSize(1500,1000);
        background.setVisible(true);
        homePanel.add(background);

        JLabel logo=new JLabel();
        logo.setIcon(new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\logo.png"));
        logo.setBounds(214,43,500,300);
        logo.setVisible(true);
        homePanel.add(logo,0);

        JLabel userLabel = new JLabel("用户名:");
        userLabel.setBounds(750,500,150,80);
        userLabel.setFont(new  java.awt.Font("华文行楷", Font.BOLD,  30));
        homePanel.add(userLabel,0);

        JTextField userText = new JTextField(20);
        userText.setBounds(900,500,300,60);
        userText.setFont(new  java.awt.Font("华文行楷", Font.BOLD,  30));
        homePanel.add(userText,0);

        JLabel passwordLabel = new JLabel("密码:");
        passwordLabel.setBounds(750,600,150,80);
        passwordLabel.setFont(new  java.awt.Font("华文行楷", Font.BOLD,  30));
        homePanel.add(passwordLabel,0);

        JTextField passwordText = new JTextField(20);
        passwordText.setBounds(900,600,300,60);
        passwordText.setFont(new  java.awt.Font("华文行楷", Font.BOLD,  30));
        homePanel.add(passwordText,0);

        JButton loginButton = new JButton("登录");
        loginButton.setBounds(900,700,220,70);
        loginButton.setFont(new  java.awt.Font("华文行楷", Font.BOLD,  30));
        homePanel.add(loginButton,0);

        f.add(homePanel);
        f.repaint();
        class button1hander implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                String username=userText.getText();
                String password= passwordText.getText();
                nowUsername=username;
                try {
                    boolean res=Login(username,password);
                    if(res){
                        sendMessage(Const.login,nowUsername,null);
                        state=Const.login;
                        listener();
                        f.remove(homePanel);
                        initHall();
                        f.repaint();
                    }
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
            }

        }
        loginButton.addActionListener(new button1hander());
    }

    private void initHall() throws SQLException {
        hallPanel=new JPanel();
        hallPanel.setVisible(true);
        hallPanel.setBounds(0,0,width,height);

        ImageIcon image = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\hall.jpg");
        //图片自适应窗口尺寸
        image.setImage(image.getImage().getScaledInstance(width, height,Image.SCALE_DEFAULT ));
        JLabel background=new JLabel();
        background.setIcon(image);
        background.setSize(width, height);
        background.setVisible(true);
        hallPanel.add(background);

        ImageIcon image2 = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\head.png");
        image2.setImage(image2.getImage().getScaledInstance(200 ,200,Image.SCALE_DEFAULT ));
        JLabel head=new JLabel();
        head.setIcon(image2);
        head.setBounds(50, 100,200,200);
        hallPanel.add(head,0);

        JLabel name=new JLabel("用户名:"+nowUsername);
        name.setBounds(50, 350,400,50);
        name.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        hallPanel.add(name,0);

        JLabel Num=new JLabel("总场次:"+allNum);
        Num.setBounds(50, 450,400,50);
        Num.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        hallPanel.add(Num,0);

        JLabel vic=new JLabel("胜场:"+victory);
        vic.setBounds(50, 550,400,50);
        vic.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        hallPanel.add(vic,0);

        JButton create = new JButton("创建房间");
        create.setVisible(true);
        create.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        create.setBounds(50,650,200,100);
        hallPanel.add(create,0);

        JButton flush = new JButton("换一批");
        flush.setVisible(true);
        flush.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        flush.setBounds(50,800,200,100);
        hallPanel.add(flush,0);

        RButton[] rooms =new RButton[20];
        JLabel[] labels =new JLabel[20];
        for(int i=0;i<4;i++){
            for(int j=0;j<5;j++){
                rooms[i*5+j]=new RButton("空房间");
                rooms[i*5+j].setFont(new java.awt.Font("宋体", Font.BOLD, 20));
                rooms[i*5+j].setBounds(400+j*220,100+i*200,100,100);
                hallPanel.add(rooms[i*5+j],0);

                labels[i*5+j]=new JLabel("空房间");
                labels[i*5+j].setFont(new java.awt.Font("宋体", Font.BOLD, 20));
                labels[i*5+j].setBounds(410+j*220,60+i*200,150,50);
                hallPanel.add(labels[i*5+j],0);
            }
        }

        flushTime=0;
        flushRooms(labels,rooms);
        f.add(hallPanel);

        class buttonHandler implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                String s=e.getActionCommand();
                if(e.getSource()==create){
                    try {
                        f.remove(hallPanel);
                        sendMessage(Const.searching,nowUsername,null);
                        state=Const.searching;
                        initRoom();
                        f.repaint();
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
                else if(e.getSource()==flush){
                    try {
                        flushTime++;
                        flushRooms(labels,rooms);
                        JOptionPane.showMessageDialog(null, "换一批房间成功");
                    } catch (SQLException ex) {
                        throw new RuntimeException(ex);
                    }
                }
                else if(s.equals("空房间")){
                    JOptionPane.showMessageDialog(null, "空房间不可加入");
                }
                else{
                    if(state==Const.login){
                        try {
                            int n = JOptionPane.showConfirmDialog(null, "确认加入"+s+"的房间吗?", "标题",JOptionPane.YES_NO_OPTION);
                            if(n==0){
                                sendMessage(Const.ask,s,null);
                                state=Const.ask;
                                otherUser=s;
                                JOptionPane.showMessageDialog(null, "正在等待房主同意...");
                            }
                        } catch (Exception ex) {
                            throw new RuntimeException(ex);
                        }
                    }else if(state==Const.ask){
                        JOptionPane.showMessageDialog(null, "请勿同时加入多个房间");
                    }
                }
            }
        }
        create.addActionListener(new buttonHandler());
        flush.addActionListener(new buttonHandler());
        for(int i=0;i<20;i++) rooms[i].addActionListener(new buttonHandler());

        int delay = 10000;    //时间间隔，单位为毫秒
        ActionListener timer = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    if(state==Const.login){
                        flushTime=0;
                        flushRooms(labels,rooms);
                        JOptionPane.showMessageDialog(null, "房间列表已超时自动刷新");
                    }
                } catch (SQLException ex) {
                    throw new RuntimeException(ex);
                }
            }
        };
        new Timer(delay,timer).start();
    }

    private void flushRooms(JLabel[] labels,RButton[] rooms) throws SQLException {
        String sql="select * from room";
        Statement preparedStatement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
        ResultSet resultSet=preparedStatement.executeQuery(sql);
        java.util.List<String> allRooms=new ArrayList<>();

        while(resultSet.next()){
            allRooms.add(resultSet.getString(2));
        }
        if(flushTime*20>allRooms.size()) flushTime=0;

        f.remove(hallPanel);

        for(int i=0;i<4;i++){
            for(int j=0;j<5;j++) {
                int index = i * 5 + j + flushTime * 20;
                if (index < allRooms.size()) {
                    String name = allRooms.get(index);
                    rooms[i * 5 + j].setText(name);
                    labels[i * 5 + j].setText("下方按钮加入");
                } else {
                    rooms[i * 5 + j].setText("空房间");
                    labels[i * 5 + j].setText("空房间");
                }
            }
        }

        f.add(hallPanel);
        f.repaint();
    }

    private boolean Login(String username,String password) throws SQLException {
        try{
            String sql = "select * from User where username = ?";
            PreparedStatement state1 = connection.prepareStatement(sql);
            state1.setString(1, username);
            ResultSet Rset=state1.executeQuery();
            if(!Rset.next()){
                allNum=0;
                victory=0;
                String sql2 = "INSERT INTO User (username, password,num,victory) VALUES (?, ?, ?,?)";
                PreparedStatement  notExist= connection.prepareStatement(sql2);
                notExist.setString(1, username);
                notExist.setString(2, password);
                notExist.setInt(3, 0);
                notExist.setInt(4, 0);
                notExist.execute();
                JOptionPane.showMessageDialog(null, "注册新用户成功");
                return true;
            }else{
                String returnPassword=Rset.getString(2);
                allNum=Rset.getInt(3);
                victory=Rset.getInt(4);
                if(returnPassword.equals(password)){
                    JOptionPane.showMessageDialog(null, "登录成功");
                    return true;
                }else{
                    JOptionPane.showMessageDialog(null, "登录失败", "Title",JOptionPane.ERROR_MESSAGE);
                    return false;
                }
            }
        }catch (Exception e){
            System.out.println(Arrays.toString(e.getStackTrace()));
        }
        return false;
    }

    private void initRoom() throws Exception{
        //创建登录界面背景图片
        ImageIcon backImage = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\background.jpg");
        //图片自适应窗口尺寸
        backImage.setImage(backImage.getImage().getScaledInstance(width, height,Image.SCALE_DEFAULT ));
        JLabel background=new JLabel();
        background.setIcon(backImage);
        background.setSize(width, height);
        background.setVisible(true);
        f.add(background);

        //背景棋盘
        ImageIcon image = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\qipan.png");
        image.setImage(image.getImage().getScaledInstance(800, 800, Image.SCALE_DEFAULT));
        JLabel board = new JLabel();
        board.setIcon(image);
        board.setBounds(30, 90, 800, 800);
        board.setVisible(true);
        f.add(board, 0);

        ImageIcon image2 = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\attention.png");
        image2.setImage(image2.getImage().getScaledInstance(width / 4, height / 5, Image.SCALE_DEFAULT));
        JLabel attention = new JLabel();
        attention.setIcon(image2);
        attention.setBounds(width * 2 / 3 + 80, height / 40 + 100, width / 4, height / 5);
        attention.setVisible(true);
        f.add(attention, 0);

        //对话框
        recordTalk = new JTextArea();
        recordTalk.setBounds(width * 2 / 3 + 80, height * 8 / 40 + 120, width / 4, height / 2);
        recordTalk.setEditable(false);
        recordTalk.setFont(new java.awt.Font("宋体", Font.BOLD, 20));
        recordTalk.append("您好！用户:"+nowUsername+"\n");
        f.add(recordTalk, 0);

        JTextField sendTalk = new JTextField();
        sendTalk.setBounds(width * 2 / 3 + 80, height * 28 / 40 + 150, width / 4, height / 16);
        f.add(sendTalk, 0);

        RButton restart = new RButton("重新开始");
        restart.setBounds(870, height / 40 + 100, 167, 167);
        restart.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        f.add(restart, 0);

        RButton Repentance = new RButton("悔棋");
        Repentance.setBounds(870, height / 40 + 300, 167, 167);
        Repentance.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        f.add(Repentance, 0);

        RButton defeat = new RButton("认输");
        defeat.setBounds(870, height / 40 + 500, 167, 167);
        defeat.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        f.add(defeat, 0);

        RButton exit = new RButton("退出房间");
        exit.setBounds(870, height / 40 + 700, 167, 167);
        exit.setFont(new java.awt.Font("华文行楷", Font.BOLD, 30));
        f.add(exit, 0);

        time = new JLabel("对局进行时长  00:00:00");
        time.setBounds(width * 2 / 3 + 140, height / 40 + 160, 300, 100);
        time.setFont(new java.awt.Font("华文行楷", Font.BOLD, 25));
        f.add(time, 0);

        class button1hander implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                try{
                    if(e.getSource()==exit){
                        int n = JOptionPane.showConfirmDialog(null, "确定退出房间么？", "标题",JOptionPane.YES_NO_OPTION);
                        if(n==0){
                            if(otherUser!=null) sendMessage(Const.end,nowUsername,"exit");

                            cleanBoard();
                            sec=0;
                            min=0;
                            hour=0;
                            otherUser=null;
                            state=Const.login;
                            chessColor=0;

                            f.remove(background);
                            f.remove(board);
                            f.remove(attention);
                            f.remove(recordTalk);
                            f.remove(sendTalk);
                            f.remove(restart);
                            f.remove(Repentance);
                            f.remove(defeat);
                            f.remove(exit);
                            f.remove(time);
                            initHall();
                            f.repaint();
                        }
                    }
                    if(e.getSource()==restart){
                        if(otherUser != null){
                            sendMessage(Const.restart,null,"0");
                            JOptionPane.showMessageDialog(null, "正在请求对方同意");
                        }else JOptionPane.showMessageDialog(null, "尚未匹配到对手，无法重新开始", "Title",JOptionPane.ERROR_MESSAGE);
                    }
                    if(e.getSource()==defeat){
                        if(otherUser != null&&state!=Const.end){
                            int n = JOptionPane.showConfirmDialog(null, "确定认输么？", "标题",JOptionPane.YES_NO_OPTION);
                            if(n==0){
                                sendMessage(Const.end,nowUsername,"-1");
                                state=Const.end;
                                recordTalk.append("【系统】游戏结束！很遗憾您输了\n");
                                JOptionPane.showMessageDialog(null, "游戏结束！很遗憾您输了");
                            }
                        }else JOptionPane.showMessageDialog(null, "当前状态无法认输", "Title",JOptionPane.ERROR_MESSAGE);
                    }
                    if(e.getSource()==Repentance){
                        if(otherUser != null && !blackChess.isEmpty()&&state!=Const.end){
                            sendMessage(Const.regret,nowUsername,"0");
                        }else JOptionPane.showMessageDialog(null, "当前状态无法悔棋", "Title",JOptionPane.ERROR_MESSAGE);
                    }
                }catch (Exception exception){
                    System.out.println(Arrays.toString(exception.getStackTrace()));
                }
            }
        }

        sendTalk.addKeyListener(new java.awt.event.KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                int k=e.getKeyCode();
                if(k==java.awt.event.KeyEvent.VK_ENTER){
                    try {
                        if(otherUser != null){
                            String txt=sendTalk.getText();
                            sendMessage(Const.send,otherUser,txt);
                            String source="【"+nowUsername+"】 ";
                            source = getStringTime(source);
                            source+='\n';
                            recordTalk.append(source);
                            recordTalk.append(txt+"\n");
                            sendTalk.setText("");
                        }
                        else JOptionPane.showMessageDialog(null, "尚未匹配到对手，无法开始聊天", "Title",JOptionPane.ERROR_MESSAGE);
                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
            }
        });

        board.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(state==Const.play){
                    try {
                        super.mouseClicked(e);
                        int x=e.getX();
                        int y=e.getY();
                        int i=x/43;
                        int j=y/43;
                        int finalX=25+43*i;
                        int finalY=85+43*j;
                        if(boardRecord[i][j]!=0){
                            JOptionPane.showMessageDialog(null, "同一位置不能重复落子！", "Title",JOptionPane.ERROR_MESSAGE);
                        }
                        boardRecord[i][j]=chessColor;
                        drawChess(finalX,finalY,chessColor);
                        sendMessage(Const.play,null,finalX+" "+finalY);

                        int result=judgeWin(i,j,chessColor);
                        if(result==1){
                            state=Const.end;
                            sendMessage(Const.end,null,"1");
                            recordTalk.append("【系统】恭喜您赢了！\n");
                            JOptionPane.showMessageDialog(null, "恭喜您赢了！");
                        }

                    } catch (Exception ex) {
                        throw new RuntimeException(ex);
                    }
                }
            }
        });

        exit.addActionListener(new button1hander());
        restart.addActionListener(new button1hander());
        defeat.addActionListener(new button1hander());
        Repentance.addActionListener(new button1hander());
    }

    private void drawChess(int finalX,int finalY,int color) throws Exception {
        ImageIcon chess;
        if(color==1){
            chess = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\black.png");
            chess.setImage(chess.getImage().getScaledInstance(40, 40, Image.SCALE_DEFAULT));
        }else{
            chess = new ImageIcon("G:\\D\\2021\\Java应用技术\\hm5\\client\\pic\\white.png");
            chess.setImage(chess.getImage().getScaledInstance(40, 40, Image.SCALE_DEFAULT));
        }

        JLabel newChess=new JLabel(chess);
        newChess.setBounds(finalX,finalY,40,40);
        newChess.setVisible(true);
        f.add(newChess,0);
        f.repaint();

        int i=(finalX-25)/43;
        int j=(finalY-85)/43;
        
        state=Const.wait;

        if(color==1) blackChess.add(newChess);
        else whiteChess.add(newChess);
    }

    private int judgeWin(int Row,int Column,int color) {
        int sum=0;
        int i,j;
        //横向
        int from= Math.max(Column - 5, 0);
        int to= Math.min(Column + 5, 18);
        for(j=from;j<=to;j++){
            if(boardRecord[Row][j]==color){
                sum++;
                if(sum==5) return 1;
            }
            else sum=0;
        }
        sum=0;
        //纵向
        from= Math.max(Row - 5, 0);
        to= Math.min(Row + 5, 18);
        for(j=from;j<=to;j++){
            if(boardRecord[j][Column]==color){
                sum++;
                if(sum==5) return 1;
            }
            else sum=0;
        }
        sum=0;
        //左上到右下
        for(int index=-5;index<=5;index++){
            i=Row+index;
            j=Column+index;
            if(i<0||j<0||i>18||j>18) continue;
            if(boardRecord[i][j]==color){
                sum++;
                if(sum==5) return 1;
            }
            else sum=0;
        }
        //右上到左下
        for(int index=-5;index<=5;index++){
            i=Row+index;
            j=Column-index;
            if(i<0||j<0||i>18||j>18) continue;
            if(boardRecord[i][j]==color){
                sum++;
                if(sum==5) return 1;
            }
            else sum=0;
        }
        return 0;
    }

    private String getStringTime(String txt) {
        if (hour < 10) txt += "0";
        txt += hour;
        txt += ":";
        if (min < 10) txt += "0";
        txt += min;
        txt += ":";
        if (sec < 10) txt += "0";
        txt += sec;
        return txt;
    }

    private void sendMessage(int flag,String u, String message) throws Exception{
        try{
            //this.os.write(message.getBytes());
            this.os.writeObject(new communication(flag,u,message));
            this.os.flush();
        }catch (Exception e){
        }
    }

    private void initFrame() {
        f=new JFrame("五子棋");
        f.setSize(width,height);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                try {
                    sendMessage(Const.logout,nowUsername,null);
                    socket.close();
                } catch (Exception ex) {
                    throw new RuntimeException(ex);
                }
                super.windowClosing(e);
            }
        });
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setLayout(null);
        f.setVisible(true);
        f.setResizable(false);

        initHome();
        f.repaint();
    }
}
